import puppeteer from "puppeteer";

const MAX_WSE:number = 5;  //启动几个浏览器 
let WSE_LIST:Array<string> = []; //存储browserWSEndpoint列表
let tmp:number = 0;
let count:number = 0; //并发数
const browserPara = {
    headless:true,
    args: [
    '--disable-gpu',
    '--disable-dev-shm-usage',
    '--disable-setuid-sandbox',
    '--no-first-run',
    '--no-sandbox',
    '--no-zygote',
    '--single-process',
]
}
export function browserInit():Promise<string>{
    return new Promise((resolve, rej) => {
        (async () => {
            let count:number = 0;
            let errArr:Array<number> = [];
            for(let i:number = 0; i < MAX_WSE; i++){
                try {
                    const browser:puppeteer.Browser = await puppeteer.launch(browserPara);
                    (await browser.pages())[0].goto("http://www.zfjw.xupt.edu.cn/jwglxt/xtgl/index_cxYhxxIndex.html", {timeout: 10000});
                    let browserWSEndpoint:string = await browser.wsEndpoint();
                    WSE_LIST.push(browserWSEndpoint);
                    count++;
                    console.log(`第${i}号浏览器启动成功（${count}/${MAX_WSE}）`);
                    if(i === MAX_WSE - 1) {
                        resolve("yes");
                    }
                }
                catch(err) {
                    console.log(err);
                    errArr.push(i);
                    if(i ===  MAX_WSE - 1) {
                        for(let j = 0; j < errArr.length; j++) {
                            const browser:puppeteer.Browser = await puppeteer.launch(browserPara);
                            (await browser.pages())[0].goto("http://www.zfjw.xupt.edu.cn/jwglxt/xtgl/index_cxYhxxIndex.html");
                            let browserWSEndpoint:string = await browser.wsEndpoint();
                            WSE_LIST.push(browserWSEndpoint);
                            count++;
                            console.log(`第${errArr[j]}号浏览器重启成功（${count}/${MAX_WSE}）`);
                            if(j === errArr.length - 1) {
                                resolve("yes");
                            }
                        }
                        
                    }
                }
            }
        })();     
    })
}

async function newBro(browser:puppeteer.Browser, um:number) {
    try {
        await browser.close();
    } finally {
        try {
        
            const abrowser = await puppeteer.launch(browserPara);
            (await abrowser.pages())[0].goto("http://www.zfjw.xupt.edu.cn/jwglxt/xtgl/index_cxYhxxIndex.html");
            let browserWSEndpoint = await abrowser.wsEndpoint();
            WSE_LIST[um] = browserWSEndpoint;
            count--;
            console.log(`${um}号浏览器重启成功` + ` 当前并发数${count}`);
        } catch {
            const abrowser = await puppeteer.launch(browserPara);
            (await abrowser.pages())[0].goto("http://www.zfjw.xupt.edu.cn/jwglxt/xtgl/index_cxYhxxIndex.html");
            let browserWSEndpoint = await abrowser.wsEndpoint();
            WSE_LIST[um] = browserWSEndpoint;
            count--;
            console.log(`${um}号浏览器重启成功` + ` 当前并发数${count}`);
        }
    } 
    
}

function verification(id:string, password:string):Promise<any> {
    let flag:boolean = false;
    console.log({id:id, pass:password});
    return new Promise((resolve, rej) => {
        (async () => {
            if(count === MAX_WSE) {
                console.log(count + "超过并发数");
                let result:object = {
                    state: 1,
                    tips: "任务繁忙，请稍后重试"
                }
                resolve(result);
            } else {
                count++;
                tmp = (tmp + 1)%MAX_WSE;
                const um = tmp;
                let browserWSEndpoint = WSE_LIST[um];
                console.log(`第${um}号浏览器正在工作`);
                const browser = await puppeteer.connect({browserWSEndpoint});
                const page = (await browser.pages())[0];
                await page.setRequestInterception(true);  
                page.on('request', interceptedRequest => {
                    //判断如果是 图片请求  就直接拦截  
                    if (interceptedRequest.url().split("?")[0].match(/.png$/) || interceptedRequest.url().split("?")[0].match(/.jpg$/))
                        interceptedRequest.abort();   //终止请求
                    else if(interceptedRequest.url() === "http://www.zfjw.xupt.edu.cn/jwglxt/xtgl/index_cxYhxxIndex.html") {
                        interceptedRequest.continue();//弹出
                        flag = true;
                    } else 
                        interceptedRequest.continue();
                });
                try {
                    await page.waitForSelector("#yhm", {timeout: 1000});
                    await page.type('#yhm', id);
                    await page.type('#mm', password);
                    await page.click("#dl");
                    await page.waitForNavigation({timeout: 5000});
                } catch(err) {
                    console.log(err);
                    newBro(browser, um);
                    let result:object = {
                        state: 1,
                        tips: "数据获取异常，请重试"
                    }
                    resolve(result);
                }
                if(flag) {
                    //await page.waitFor(5000);
                    const name:string = await page.$eval(".media-heading", ele => ele.innerHTML);
                    const text:string = await page.$eval(".media-body>p", ele => ele.innerHTML);
                    await page.close();
                    let result:object = {
                        state: 0,
                        name: name,
                        class: text.split(" ")[1],

                    };
                    console.log(result);
                    newBro(browser, um);
                    resolve(result); 
                }
                else {
                    await page.waitForSelector("#tips>span", {timeout: 5000});
            
                    const tips:string = await page.$eval("#tips", ele => ele.innerHTML);
                    await page.close();
                    let result:object = {
                        state: 0,
                        tips: tips.split("</span>")[1]
                    };
                    newBro(browser, um);
                    resolve(result);
                }
            }
            
        })();
    });
}

export default verification;

